import Objects from "../../utils/objects";
import Log from "../../utils/log";

function SpaceAreaMeasurer(viewer) {
    this.viewer = viewer;
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    //线
    this.polyline = null;
    //面
    this.polygon = null;
    //面积标签
    this.floatLabel = null;
    this.filterEntityArr = [this.floatLabel, this.polyline, this.polygon];
    this.positions = [];

    this._firstPoint = null;
    this._lastCartesian = null;
    this._totalDistance = 0;

    SpaceAreaMeasurer.MEASURERS.push(this);

    this.stopped = false;
}

SpaceAreaMeasurer.MEASURERS = [];
SpaceAreaMeasurer._HANDLER = null;

SpaceAreaMeasurer.newInstance = function(viewer) {
    return new SpaceAreaMeasurer(viewer);
};

SpaceAreaMeasurer.lastMeasurer = function() {
    if (SpaceAreaMeasurer.MEASURERS.length === 0) {
        throw new Error("尚未拥有实例！！！");
    }

    return SpaceAreaMeasurer.MEASURERS[SpaceAreaMeasurer.MEASURERS.length - 1];
};

SpaceAreaMeasurer.prototype.start = function() {
    let that = this;
    that.handler.setInputAction(function(evt) {
        let cartesian = that.getCatesian3FromPX(evt.position, that.viewer, that.filterEntityArr);
        if (that._firstPoint === null) {
            that._firstPoint = cartesian;
        }
        if (!cartesian) return;
        //that.tsLabel.label.text = "单机新增点\n双击结束" ;
        if (that.positions.length === 0) {
            that.positions.push(cartesian);
            that.positions.push(cartesian.clone());
        } else {
            that.positions.push(cartesian);
        }

        if (that.positions.length === 3) {
            if (!Cesium.defined(that.polyline)) {
                that.polyline = that.createLine();
            }
        }
        if (that.positions.length === 4) {
            if (!Cesium.defined(that.polygon)) {
                that.viewer.entities.remove(that.polyline);
                that.polygon = that.createGon();
                that.floatLabel = that.createLabel(cartesian, "");
            }
        }
        that.positions.pop();
        that.positions.push(cartesian);
        if (that.positions.length > 2) {
            let distance = Cesium.Cartesian3.distance(cartesian, that._lastCartesian);
            that._totalDistance += distance;
            console.log(that._totalDistance);
        }
        that._lastCartesian = cartesian;
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};

SpaceAreaMeasurer.prototype.stop = function() {
    if (!this.stopped) {
        let that = this;
        that._totalDistance += Cesium.Cartesian3.distance(that._firstPoint, that._lastCartesian);

        this.showLable();
        this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.stopped = true;
    }
};

SpaceAreaMeasurer.prototype.showLable = function() {
    let that = this;
    if (that.polygon) {
        let area = that.getAreaAndCenter(that.positions).area;
        let center = that.getAreaAndCenter(that.positions).center;
        let text = that.formatArea(area);
        let textdistance = that.formatDistance(that._totalDistance);
        that.floatLabel.label.text = "面积：" + text + "\n" + "长度：" + textdistance;
        if (center) that.floatLabel.position.setValue(center);
    }
};

SpaceAreaMeasurer.prototype.destroy = function() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.viewer.entities.remove(this.polygon);
    this.viewer.entities.remove(this.polyline);
    this.viewer.entities.remove(this.floatLabel);
    SpaceAreaMeasurer.MEASURERS = SpaceAreaMeasurer.MEASURERS.filter(measurer => measurer !== this);
};

SpaceAreaMeasurer.destroyAll = function() {
    SpaceAreaMeasurer.MEASURERS.forEach(measurer => measurer.destroy());
    if (Objects.notNull(SpaceAreaMeasurer.handler) && !SpaceAreaMeasurer.handler.isDestroyed()) {
        Log.debug("start destroy SpaceAreaMeasurer._HANDLER...");
        SpaceAreaMeasurer.handler.destroy();
    }
    SpaceAreaMeasurer.MEASURERS = [];
};

SpaceAreaMeasurer.prototype.createLine = function() {
    let that = this;
    return this.viewer.entities.add({
        polyline: {
            positions: new Cesium.CallbackProperty(function() {
                return that.positions;
            }, false),
            show: true,
            clampToGround: false,
            //disableDepthTestDistance: Number.POSITIVE_INFINITY,
            disableDepthTestDistance: 0,
            material: Cesium.Color.YELLOW,
            width: 3
        }
    });
};

SpaceAreaMeasurer.prototype.createGon = function() {
    let that = this;
    return this.viewer.entities.add({
        polygon: new Cesium.PolygonGraphics({
            hierarchy: new Cesium.CallbackProperty(function() {
                return new Cesium.PolygonHierarchy(that.positions);
            }, false),
            clampToGround: false,
            //disableDepthTestDistance: Number.POSITIVE_INFINITY,
            disableDepthTestDistance: 0,
            show: true,
            fill: true,
            outlineColor: new Cesium.Color.fromCssColorString("rgba(232,229,3,1)"),
            material: new Cesium.Color.fromCssColorString("rgba(232,229,3,0.6)")
        })
    });
};

SpaceAreaMeasurer.prototype.createLabel = function(c, text) {
    if (!c) return;
    return this.viewer.entities.add({
        position: c,
        label: {
            text: text || "",
            font: "24px Helvetica",
            fillColor: Cesium.Color.SKYBLUE,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 2,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            verticalOrigin: Cesium.VerticalOrigin.CENTER
        }
    });
};

SpaceAreaMeasurer.prototype.getAreaAndCenter = function(positions) {
    if (!positions || positions.length < 1) return;
    let cartographics = [];
    let turfPoints = [];
    for (let i = 0; i < positions.length; i++) {
        let cartesian3 = positions[i];
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
        cartographics.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]);
        turfPoints.push(turf.point([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]));
    }
    if (!cartographics.length) return;
    cartographics = cartographics.concat([cartographics[0]]);
    let polygon = turf.polygon([cartographics]);
    let area = turf.area(polygon);

    //获取当前范围的中心点
    let features = turf.featureCollection(turfPoints);
    let turfCenter = turf.center(features);
    let center = turfCenter.geometry.coordinates;

    return {
        area: area,
        center: Cesium.Cartesian3.fromDegrees(center[0], center[1])
    };
};

SpaceAreaMeasurer.prototype.formatArea = function(num, dw) {
    if (!num) return;
    let res = null;
    if (!dw) {
        dw = "平方米";
        let n = Number(num).toFixed(2);
        res = n + dw;
    }
    if (dw === "平方千米" || dw === "平方公里") {
        let n = (Number(num) / 1000000).toFixed(2);
        res = n + dw;
    }
    return res;
};

SpaceAreaMeasurer.prototype.formatDistance = function(num, dw) {
    if (!num) return;
    let res = null;
    if (!dw) {
        dw = "米";
        let n = Number(num).toFixed(2);
        res = n + dw;
    }
    if (dw === "平方千米" || dw === "平方公里") {
        let n = (Number(num) / 1000000).toFixed(2);
        res = n + dw;
    }
    return res;
};

SpaceAreaMeasurer.prototype.getCatesian3FromPX = function(px, viewer, noPickEntityArr) {
    let picks = viewer.scene.drillPick(px);
    viewer.render();
    let getOnModel = false;
    let that = this;
    let cartesian;
    if (viewer.scene.pickPositionSupported) {
        //检测是否支持拾取坐标
        for (let i = 0; i < picks.length; i++) {
            let pickedObject = picks[i];
            for (let j = 0; j < noPickEntityArr.length; j++) {
                let noPickEntity = noPickEntityArr[j];
                if (that.hasPickedModel(pickedObject, noPickEntity)) {
                    getOnModel = true;
                }
            }
        }
    }
    if (getOnModel) {
        cartesian = viewer.scene.pickPosition(px);
    } else {
        let ray = viewer.camera.getPickRay(px);
        if (!ray) return null;
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
    }
    return cartesian;
};

SpaceAreaMeasurer.prototype.hasPickedModel = function(pickedObject, noPickEntity) {
    if (!noPickEntity) return true;
    if (Cesium.defined(pickedObject.id)) {
        let entity = pickedObject.id;
        if (noPickEntity && entity === noPickEntity) return false;
    }

    if (Cesium.defined(pickedObject.primitive)) {
        let primitive = pickedObject.primitive;
        if (noPickEntity && primitive === noPickEntity) return false;
    }
    return true;
};

export default SpaceAreaMeasurer;
